#include<cstdio>
#include<cstring>

#include<Winsock2.h>

#pragma comment(lib, "Ws2_32")

void SendFile(SOCKET soc) {
  const char file_name[] = "Linux.pdf";
  FILE* file = fopen(file_name, "rb");
  if (file != NULL) {
		// send header that includes a length value.
	  fseek(file, 0L, SEEK_END);
		int file_size = ftell(file);
		fseek(file, 0L, SEEK_SET);
		char header[15] = {'\0'};
		int required_size = sprintf(header, "length:%d~", file_size);
		if (send(soc, header, required_size, 0) == SOCKET_ERROR) {
		  puts("send data error!");
		}
		// send data to client.
	  const int kBufReadLen = 1024;
	  char buf_read[kBufReadLen] = {'\0'};
		int result = 0;
	  do {
	    result = fread(buf_read, sizeof(char), kBufReadLen, file);
	    int result2 = send(soc, buf_read, kBufReadLen, 0);
	    if (result2 == SOCKET_ERROR) {
	      puts("send data error!");
	      return; 
	    }
	    memset(buf_read, 0, kBufReadLen);
	  } while (result == kBufReadLen);
		// read file error.
    if (0 == feof(file)) {
	    puts("read data from file error!");
	    return;
	  }
    closesocket(soc);
		fclose(file);
	}
}

int main() {
  WSADATA wsa_data;
  WORD version = MAKEWORD(2,2);
  int result = WSAStartup(version, &wsa_data);
  if (result == 0) {
    SOCKET serv_soc = socket(AF_INET, SOCK_STREAM, 0);
    if (serv_soc != INVALID_SOCKET) {
      const int http_default_port = 80;
      sockaddr_in serv_addr;
      serv_addr.sin_family = AF_INET;
      serv_addr.sin_port = htons(http_default_port);
      serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
      result = bind(serv_soc, (sockaddr*)&serv_addr, sizeof(serv_addr));
      if (result == 0) {
        result = listen(serv_soc, SOMAXCONN);
				if (result == 0) {
          sockaddr_in accept_addr;
	        int addrlen = sizeof(accept_addr);
	        SOCKET accept_soc = accept(serv_soc,
                                     (sockaddr*)&accept_addr,
																		 &addrlen);
	        if (accept_soc != INVALID_SOCKET) {
					  // establish connect successfully.
					  // send Linux.pdf file to client.
            SendFile(accept_soc);  
	        }
	      }
      }
			closesocket(serv_soc);
    }
		WSACleanup();
  }

  return 0;
}
